/* Nama File : segiempat.cpp                        */
/* Deskripsi : Implementasi dari class SegiEmpat    */
/* Anggota Kelompok : Dekha Anggareska 13510050		*/
/*                    Fadhil Muhtadin 13510070		*/
/*                    Muhammad Iqbal 13510064		*/
/*                    Yulius Nainggolan 13510090	*/

#include "polygon.h"
#include <iostream>
using namespace std;

	Polygon::Polygon() : Bidang(5){
	// konstruktor bidang
	// I.S. polygon belum ada
	// F.S. polygon tercipta
		aCorner = new Cell [nSudut];
	};
	
	Polygon::Polygon(int n) : Bidang(n){
	// ctor dengan parameter
	// I.S. polygon belum ada
	// F.S. polygon tercipta
		aCorner = new Cell [n];
	};
	
	Polygon::Polygon(const Polygon& P){
	/* CCtor Polygon */
    /* I.S. Polygon terdefinisi */
    /* F.S. Polygon baru tercipta sebagai kopi Polygon sebelumnya */
		setSudut(P.getSudut());
		aCorner = new Cell [P.getSudut()];
		for (int i=0; i<getSudut(); i++){
			setCorner(i, P.getCorner(i));
		}
	};
	
	Polygon::~Polygon() {
	/* Destruktor Polygon */
	/* I.S. Polygon terdefinisi */
    /* F.S. Polygon dimusnahkan */ 
		delete [] aCorner;
		cout << "dtor polygon" << endl;
	};
	
    Polygon& Polygon::operator=(const Polygon& P){
    /* operator assignment Polygon */
    /* I.S. Polygon input terdefinisi */
    /* F.S. Polygon output sama dengan input dengan alokasi memori tersendiri */
		delete [] aCorner;
		setSudut(P.getSudut());
		aCorner = new Cell [P.getSudut()];
		for (int i=0; i<getSudut(); i++){
			setCorner(i, P.getCorner(i));
		}
		return *this;
	};
   
    Cell Polygon::getCorner(int i) const{
	/* Mengembalikan nilai Cell dari array Cell berindeks i */
		return aCorner[i];
	};
	
    void Polygon::setCorner(int i, Cell C1){
	/* Mengeset nilai Cell sudut berindeks i dengan Cell input */
	/* I.S. Polygon terdefinisi */
	/* F.S. Cell dalam array berindeks i == Cell input */
		aCorner[i]=C1;
	};
	
	int Polygon::isPointInside(Cell PS) {
	/* Mengembalikan 1 bila Cell input berada dalam Polygon, 0 bila tidak */
		cout << "sebelum nIntersect" << endl;
		float nIntersect = 0;
		int nSudutUp = 0;
		int nSudutDown = 0;
		
		cout << "sebelum most cek" << endl;
		if (PS.IsBelow(TopMostPoint())) {return 0;}
		else if (PS.IsAbove(BottomMostPoint())) {return 0;}
		else {
		for (int i=0; i<=getSudut()-2; i++) {
			if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 1) {nIntersect++;}
			else if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 3) {nIntersect = nIntersect+0.5;}
			else if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 5) {nIntersect = nIntersect+0.5; nSudutUp++;}
			else if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 6) {nIntersect = nIntersect+0.5; nSudutDown++;}
			else if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 4) {return 1;}
			else if (PS.isBoundaryIntersect(getCorner(i), getCorner(i+1)) == 7) {return 1;}
		}
		if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 1) {nIntersect++;}
		else if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 3) {nIntersect = nIntersect+0.5;}
		else if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 5) {nIntersect = nIntersect+0.5; nSudutUp++;}
		else if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 6) {nIntersect = nIntersect+0.5; nSudutDown++;}
		else if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 4) {return 1;}
		else if (PS.isBoundaryIntersect(getCorner(getSudut()-1), getCorner(0)) == 7) {return 1;}
		
		if (PS.getX() == 11 && PS.getY() == 8) {
		cout << "cekIntersectpoly---------" << nSudutUp << endl;
		cout << "cekIntersectpoly---------" << nSudutDown << endl;
		cout << "cekIntersectpoly---------" <<  endl;
		}
		
		if (((nIntersect != 0) && ((int) nIntersect % 2 != 0)) && (((nSudutUp%2 != 0) && (nSudutDown%2 != 0)) || ((nSudutUp == 0) && (nSudutDown == 0)))) {return 1;}
		else if ((nIntersect != 0) && ((int) nIntersect % 2 == 0) && (nSudutDown != 0) && (nSudutDown%2 == 0)) {
			Cell Pu (PS.getX(), PS.getY()+1, 'x');
			if (isPointInside(Pu)) {return 1;}
			else {return 0;}
		}
		else if ((nIntersect != 0) && ((int) nIntersect % 2 == 0) && (nSudutUp != 0) && (nSudutUp%2 == 0)) {
			Cell Pd (PS.getX(), PS.getY()-1, 'x');
			if (isPointInside(Pd)) {return 1;}
			else {return 0;}
		}
		else {return 0;}
		}
	};
	
	Cell Polygon::TopMostPoint() {
	/* Mengembalikan Cell yang berada paling atas diantara titik sudut Polygon */
		Cell CTemp (getCorner(0));
		for (int f=0; f<getSudut(); f++) {
			if (CTemp.getY()<getCorner(f).getY()) {
				CTemp = getCorner(f);
			}
		}
		return CTemp;
	}
	
	Cell Polygon::BottomMostPoint() {
	/* Mengembalikan Cell yang berada paling bawah diantara titik sudut Polygon */
		Cell CTemp (getCorner(0));
		for (int f=0; f<getSudut(); f++) {
			if (CTemp.getY()>getCorner(f).getY()) {
				CTemp = getCorner(f);
			}
		}
		return CTemp;
	}
		